#include "Memory.h"

#include <stdlib.h>

#if defined DEBUG_MEM_LEACK
#include <list>

using namespace std;

typedef struct {
      DWORD	address;
      DWORD	size;
      char	file[64];
      DWORD	line;
  } ALLOC_INFO;

  typedef list<ALLOC_INFO*> AllocList;

  AllocList *allocList;

  void AddTrack(DWORD addr,  DWORD asize,  const char *fname, DWORD lnum)
  {
      ALLOC_INFO *info;

      if(!allocList) {
	      allocList = new(AllocList);
      }

      info = new(ALLOC_INFO);
      info->address = addr;
      strncpy(info->file, fname, 63);
      info->line = lnum;
      info->size = asize;
      allocList->insert(allocList->begin(), info);
  };

  void RemoveTrack(DWORD addr)
  {
      AllocList::iterator i;

      if(!allocList)
	      return;
      for(i = allocList->begin(); i != allocList->end(); i++)
      {
	      if((*i)->address == addr)
	      {
		      allocList->remove((*i));
		      break;
	      }
      }
  };

 void DumpUnfreed()
{
  AllocList::iterator i;
  DWORD totalSize = 0;
  char buf[1024];

  if(!allocList)
      return;

  for(i = allocList->begin(); i != allocList->end(); i++) {
      printf(/*buf,*/ "%-50s:\t\tLINE %d,\t\tADDRESS %d\t%d unfreed\n",
	      (*i)->file, (*i)->line, (*i)->address, (*i)->size);
      //OutputDebugString(buf);
      totalSize += (*i)->size;
  }
  printf(/*buf,*/ "-----------------------------------------------------------\n");
  //OutputDebugString(buf);
  printf(/*buf,*/ "Total Unfreed: %d bytes\n", totalSize);
  //OutputDebugString(buf);
};

void* operator new(size_t nSize, const char *file, int line)
{
	void *ptr = (void *)malloc(nSize);
	      AddTrack((DWORD)ptr, nSize, file, line);
	      return(ptr);
}

void *operator new[](size_t nSize, const char *file, int line)
{
	void *ptr = (void *)malloc(nSize);
	      AddTrack((DWORD)ptr, nSize, file, line);
	      return(ptr);
}

#else //defined DEBUG_MEM_LEACK

void* operator new(size_t nSize)
{
	return malloc(nSize);
}

void *operator new[](size_t nSize)
{
	return malloc(nSize);
}

#endif //defined DEBUG_MEM_LEACK

void operator delete(void* p)
{
#ifdef DEBUG_MEM_LEACK
	RemoveTrack((DWORD)p);
#endif
	free(p);
}

void operator delete[](void *p)
{
#ifdef DEBUG_MEM_LEACK
	RemoveTrack((DWORD)p);
#endif
	free(p);
}
#ifdef DEBUG_MEM_LEACK


#endif